﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ActiveStoryTouch.DataModel;
using ActiveStoryTouch.UI.Enums;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows.Markup;
using System.Windows.Ink;
using ActiveStoryTouch.DataModel.Wpf;

namespace ActiveStoryTouch.UI
{
    public class SessionManager : INotifyPropertyChanged
    {
        private PenMode _activePenMode = PenMode.Draw;
        private InkCanvas _targetInkCanvas = null;
        
        public Project CurrentProject { get; set; }
        public DataModel.Page CurrentPage { get; set; }
        public GestureManager CommonGestureManager { get; set; }
        public PenSettings ActivePenSettings { get; set; }
        public PenMode ActivePenMode
        {
            get
            {
                return _activePenMode;
            }
            set
            {
                _activePenMode = value;
                NotifyPropertyChanged("ActivePenMode");
            }
        }
        // TODO: Add in UndoRedo CommandStack and relevant classes


        public SessionManager(InkCanvas targetInkCanvas)
        {
            CurrentProject = new Project();
            AddNewPageToProject();
            _targetInkCanvas = targetInkCanvas;
            CommonGestureManager = GestureManager.LoadFromFile("Gestures.xml");
            ActivePenMode = PenMode.Draw;
            ActivePenSettings = new PenSettings(targetInkCanvas);
            NotifyPropertyChanged("CurrentProject");
            NotifyPropertyChanged("ActivePenMode");
            NotifyPropertyChanged("ActivePenSettings");
        }

        public void AddPrototypeElementToPage(PrototypeElement element)
        {
            element.UniqueId = CurrentProject.GetNextUniqueId();
            CurrentPage.PrototypeElementDictionary.Add(element.UniqueId, element);
            NotifyPropertyChanged("PrototypeElementDictionary.Values");
        }

        public void SaveCurrentPage(StrokeCollection strokes)
        {
            // TODO: There's a bug here, everytime save gets called, the same strokes are added over and over
            CurrentPage.Strokes.Clear();
            CurrentPage.Strokes.AddRange(StrokeHelper.ConvertToSerializableStrokeCollection(strokes));
        }

        public void AddNewPageToProject()
        {
            // TODO: Generate reasonable page numbers.
            long pageNumber = CurrentProject.GetNextPageNumber();
            CurrentPage = new DataModel.Page { Name = String.Format("Untitled {0}", pageNumber), PageNumber = pageNumber, UnqiueId = CurrentProject.GetNextUniqueId() };
            CurrentProject.PageDictionary.Add(CurrentPage.UnqiueId, CurrentPage);
            NotifyPropertyChanged("CurrentPage");
        }

        public void LoadPage(long uniqueId)
        {
            CurrentPage = CurrentProject.PageDictionary[uniqueId];
            NotifyPropertyChanged("CurrentPage");
        }

        public void LoadPage(DataModel.Page pageToLoad)
        {
            CurrentPage = pageToLoad;
            NotifyPropertyChanged("CurrentPage");
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion

        public void SaveProject(String fileName)
        {
            CurrentProject.SaveToFile(fileName);
            // TODO: Validate target page numbers and elements
        }

        public void LoadProject(String fileName)
        {
            CurrentProject = Project.LoadFromFile(fileName);
            if(CurrentProject.PageDictionary.Count>0)
                LoadPage(CurrentProject.PageDictionary[CurrentProject.PageDictionary.Keys.ToList()[0]]);
            ActivePenMode = PenMode.Draw;
            ActivePenSettings = new PenSettings(_targetInkCanvas);
            NotifyPropertyChanged("CurrentProject");
            NotifyPropertyChanged("ActivePenMode");
            NotifyPropertyChanged("ActivePenSettings");
        }
    }
}
